<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Advanced  Reference</title>
    <link rel="stylesheet" type="text/css" href="css/jazzy.css" />
    <link rel="stylesheet" type="text/css" href="css/highlight.css" />
    <meta charset='utf-8'>
    <script src="js/jquery.min.js" defer></script>
    <script src="js/jazzy.js" defer></script>
    
  </head>
  <body>
    <a title="Advanced  Reference"></a>
    <header>
      <div class="content-wrapper">
        <p><a href="index.html">SwipeCellKit Docs</a> (100% documented)</p>
        <p class="header-right"><a href="https://github.com/SwipeCellKit/SwipeCellKit"><img src="img/gh.png"/>View on GitHub</a></p>
      </div>
    </header>
    <div class="content-wrapper">
      <p id="breadcrumbs">
        <a href="index.html">SwipeCellKit Reference</a>
        <img id="carat" src="img/carat.png" />
        Advanced  Reference
      </p>
    </div>
    <div class="content-wrapper">
      <nav class="sidebar">
        <ul class="nav-groups">
          <li class="nav-group-name">
            <a href="Guides.html">Guides</a>
            <ul class="nav-group-tasks">
              <li class="nav-group-task">
                <a href="advanced.html">Advanced</a>
              </li>
            </ul>
          </li>
          <li class="nav-group-name">
            <a href="Classes.html">Classes</a>
            <ul class="nav-group-tasks">
              <li class="nav-group-task">
                <a href="Classes/SwipeAction.html">SwipeAction</a>
              </li>
              <li class="nav-group-task">
                <a href="Classes/SwipeCollectionViewCell.html">SwipeCollectionViewCell</a>
              </li>
              <li class="nav-group-task">
                <a href="Classes/SwipeTableViewCell.html">SwipeTableViewCell</a>
              </li>
            </ul>
          </li>
          <li class="nav-group-name">
            <a href="Enums.html">Enumerations</a>
            <ul class="nav-group-tasks">
              <li class="nav-group-task">
                <a href="Enums/ExpansionFulfillmentStyle.html">ExpansionFulfillmentStyle</a>
              </li>
              <li class="nav-group-task">
                <a href="Enums/SwipeActionStyle.html">SwipeActionStyle</a>
              </li>
              <li class="nav-group-task">
                <a href="Enums/SwipeActionsOrientation.html">SwipeActionsOrientation</a>
              </li>
              <li class="nav-group-task">
                <a href="Enums/SwipeTransitionStyle.html">SwipeTransitionStyle</a>
              </li>
              <li class="nav-group-task">
                <a href="Enums/SwipeVerticalAlignment.html">SwipeVerticalAlignment</a>
              </li>
            </ul>
          </li>
          <li class="nav-group-name">
            <a href="Protocols.html">Protocols</a>
            <ul class="nav-group-tasks">
              <li class="nav-group-task">
                <a href="Protocols/SwipeActionTransitioning.html">SwipeActionTransitioning</a>
              </li>
              <li class="nav-group-task">
                <a href="Protocols/SwipeCollectionViewCellDelegate.html">SwipeCollectionViewCellDelegate</a>
              </li>
              <li class="nav-group-task">
                <a href="Protocols/SwipeExpanding.html">SwipeExpanding</a>
              </li>
              <li class="nav-group-task">
                <a href="Protocols/SwipeTableViewCellDelegate.html">SwipeTableViewCellDelegate</a>
              </li>
            </ul>
          </li>
          <li class="nav-group-name">
            <a href="Structs.html">Structures</a>
            <ul class="nav-group-tasks">
              <li class="nav-group-task">
                <a href="Structs/ScaleAndAlphaExpansion.html">ScaleAndAlphaExpansion</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/ScaleTransition.html">ScaleTransition</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeActionTransitioningContext.html">SwipeActionTransitioningContext</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeExpansionAnimationTimingParameters.html">SwipeExpansionAnimationTimingParameters</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeExpansionStyle.html">SwipeExpansionStyle</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeExpansionStyle/Target.html">– Target</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeExpansionStyle/Trigger.html">– Trigger</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeExpansionStyle/CompletionAnimation.html">– CompletionAnimation</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeExpansionStyle/FillOptions.html">– FillOptions</a>
              </li>
              <li class="nav-group-task">
                <a href="Structs/SwipeOptions.html">SwipeOptions</a>
              </li>
            </ul>
          </li>
        </ul>
      </nav>
      <article class="main-content">
        <section>
          <section class="section">
            
            <h2 id='customizing-transitions' class='heading'>Customizing Transitions</h2>

<p>You can customize the transition behavior of individual actions by assigning a <code>transitionDelegate</code> to the <code><a href="Classes/SwipeAction.html">SwipeAction</a></code> type. </p>

<p>The provided <code><a href="Structs/ScaleTransition.html">ScaleTransition</a></code> type monitors the action button&rsquo;s visibility as it crosses the <code>threshold</code>, and animates between <code>initialScale</code> and <code>identity</code>.  This provides a <q>pop-like</q> effect as the action buttons are exposed more than 50% of their target width. </p>

<p align="center"><img src="https://raw.githubusercontent.com/jerkoch/SwipeCellKit/develop/Screenshots/Transition-Delegate.gif" /></p>
<pre class="highlight swift"><code><span class="k">let</span> <span class="nv">action</span> <span class="o">=</span> <span class="kt">SwipeAction</span><span class="p">(</span><span class="nv">style</span><span class="p">:</span> <span class="o">.</span><span class="k">default</span><span class="p">,</span> <span class="nv">title</span><span class="p">:</span> <span class="s">"More"</span><span class="p">)</span> <span class="p">{</span> <span class="n">action</span><span class="p">,</span> <span class="n">indexPath</span> <span class="k">in</span> <span class="k">return</span> <span class="p">}</span>
<span class="n">action</span><span class="o">.</span><span class="n">transitionDelegate</span> <span class="o">=</span> <span class="kt">ScaleTransition</span><span class="o">.</span><span class="k">default</span>
</code></pre>

<p>The <code><a href="Structs/ScaleTransition.html">ScaleTransition</a></code> type provides a static <code>default</code> configuration, but it can also be initiantiated with custom parameters to suit your needs.</p>

<p>You can also easily provide your own completely custom transition behavior by adopting the <code><a href="Protocols/SwipeActionTransitioning.html">SwipeActionTransitioning</a></code> protocol.  The supplied <code><a href="Structs/SwipeActionTransitioningContext.html">SwipeActionTransitioningContext</a></code> to the delegate methods reflect the current swipe state as the gesture is performed.</p>
<h2 id='customizing-expansion' class='heading'>Customizing Expansion</h2>

<p>Expansion behavior is defined by the properties available in the <code><a href="Structs/SwipeExpansionStyle.html">SwipeExpansionStyle</a></code> type: </p>

<ul>
<li><code>target</code>: The relative target expansion threshold. Expansion will occur at the specified value.</li>
<li><code>additionalTriggers</code>: Additional triggers to useful for determining if expansion should occur.</li>
<li><code>elasticOverscroll</code>: Specifies if buttons should expand to fully fill overscroll, or expand at a percentage relative to the overscroll.</li>
<li><code>completionAnimation</code>: Specifies the expansion animation completion style.</li>
<li><code>minimumTargetOverscroll</code>: Specifies the minimum amount of overscroll required if the configured target is less than the fully exposed action view.</li>
<li><code>targetOverscrollElasticity</code>: The amount of elasticity applied when dragging past the expansion target.</li>
</ul>
<h3 id='target' class='heading'>Target</h3>

<p>The target describes a location to which the view will scroll when expansion is triggered. A trigger is simply a threshold causing expansion to occur.</p>

<p>The <code><a href="Structs/SwipeExpansionStyle/Target.html">SwipeExpansionStyle.Target</a></code> enumeration defines the following target options:</p>

<ol>
<li><code>.percentage(CGFloat)</code>: Percentage of superview&rsquo;s width (0.0 to 1.0).</li>
<li><code>.edgeInset(CGFloat)</code>: Inset from superview&rsquo;s opposite edge (in points).</li>
</ol>

<p>By default, the configured <em>target</em> will also act as a trigger. For instance, if a target is configured with <code>.percentage(0.5)</code>, expansion will trigger when the view is scrolled more than 50% of its superview. </p>
<h3 id='additional-triggers' class='heading'>Additional Triggers</h3>

<p>It may be desirable to add additional triggers to complement the default target trigger. For instance, destructive expansion adds a touch threshold, triggering expansion when a touch occurs towards the opposite edge of the view. The <code><a href="Structs/SwipeExpansionStyle/Trigger.html">SwipeExpansionStyle.Trigger</a></code> enumeration defines the following options:</p>

<ol>
<li><code>.touchThreshold(CGFloat)</code>: The trigger a specified by a touch occuring past the supplied percentage in the superview (0.0 to 1.0). The action view must also be fully exposed for this trigger to activate.</li>
<li><code>.overscroll(CGFloat)</code>: The trigger is specified by the distance past the fully exposed action view (in points).</li>
</ol>
<h3 id='elastic-overscroll' class='heading'>Elastic Overscroll</h3>

<p>When <code>elasticOverscroll</code> is enabled, the action buttons will only fill 25% percent of the additional space provided to the actions view.  </p>
<h3 id='completion-animations' class='heading'>Completion Animations</h3>

<p>The completion animation occurs on touch up if expansion is actively triggered. The <code><a href="Structs/SwipeExpansionStyle/CompletionAnimation.html">SwipeExpansionStyle.CompletionAnimation</a></code> enumeration defines the following expansion animation completion style options:</p>

<ol>
<li><code>.fill(FillOptions)</code>: The default expansion button will completely expand to fill the previous place of the cell.</li>
<li><code>.bounce</code>: The expansion will bounce back from the trigger point and hide the action view, resetting the cell.</li>
</ol>

<p>For fill expansions, you can use the <code>FillOptions</code> type to configure the behavior of the fill completion animation along with the timing of the invocation of the action handler. These options are defined by the <code><a href="Enums/ExpansionFulfillmentStyle.html">ExpansionFulfillmentStyle</a></code> and <code>HandlerInvocationTiming</code>. </p>

<p>The <code><a href="Enums/ExpansionFulfillmentStyle.html">ExpansionFulfillmentStyle</a></code> allows you to configure how to resolve the actively filled state . The built-in <code>.destructive</code>, and <code>.destructiveAfterFill</code> expansion styles configure the <code><a href="Enums/ExpansionFulfillmentStyle.html">ExpansionFulfillmentStyle</a></code> to automatically perform the <code>.delete</code> when the action handler is invoked. This is done by created a <code>FillOptions</code> instance using the static <code>automatic(_ style:timing:)</code> method.  When you need to determine this behavior at runtime or coordinate deletion with other animations, you can create a <code>FillOptions</code> instance using the static <code>manual(timing:)</code> function and call <code>action.fulfull(style:)</code> asynchronously after your action handler is invoked.</p>

<p>You can use the <code>HandlerInvocationTiming</code> to configure if the action handler should be invoked <code>.with</code> the fill animation, or <code>.after</code> the fill animation completes.  Using the <code>.with</code> option behaves like the stock Mail.app, while the <code>.after</code> option behaves more like the 3rd party Mailbox and Tweetbot apps.</p>
<h3 id='built-in-styles' class='heading'>Built-in Styles</h3>

<p>The framework provides four built-in <code><a href="Structs/SwipeExpansionStyle.html">SwipeExpansionStyle</a></code> instances which configure the above components accordingly:</p>

<ol>
<li><code>.selection</code></li>
</ol>
<pre class="highlight plaintext"><code>target: .percentage(0.5)
elasticOverscroll: true
addditionalTriggers: []
completionAnimation: .bounce
</code></pre>

<ol>
<li><code>.destructive</code></li>
</ol>
<pre class="highlight plaintext"><code>target: .edgeInset(30)
elasticOverscroll: false
addditionalTriggers: [.touchThreshold(0.8)]
completionAnimation: .fill(.automatic(.delete, timing: .with))
</code></pre>

<ol>
<li><code>.destructiveAfterFill</code></li>
</ol>
<pre class="highlight plaintext"><code>target: .edgeInset(30)
elasticOverscroll: false
addditionalTriggers: [.touchThreshold(0.8)]
completionAnimation: .fill(.automatic(.delete, timing: .after))
</code></pre>

<ol>
<li><code>.fill</code></li>
</ol>
<pre class="highlight plaintext"><code>target: .edgeInset(30)
elasticOverscroll: false
addditionalTriggers: [.overscroll(30)]
completionAnimation: .fill(.manual(timing: .after))
</code></pre>
<h3 id='button-behavior' class='heading'>Button Behavior</h3>

<p>It is also possible to customize the button expansion behavior by assigning a <code>expansionDelegate</code> to the <code><a href="Structs/SwipeOptions.html">SwipeOptions</a></code> type. The delegate is invoked during the (un)expansion process and allows you to customize the display of the action being expanded, as well as the other actions in the view. </p>

<p>The provided <code><a href="Structs/ScaleAndAlphaExpansion.html">ScaleAndAlphaExpansion</a></code> type is useful for actions with clear backgrounds. When expansion occurs, the <code><a href="Structs/ScaleAndAlphaExpansion.html">ScaleAndAlphaExpansion</a></code> type automatically scales and fades the remaining actions in and out of the view. By default, if the expanded action has a clear background, the default <code><a href="Structs/ScaleAndAlphaExpansion.html">ScaleAndAlphaExpansion</a></code> will be automatically applied by the system.</p>

<p align="center"><img src="https://raw.githubusercontent.com/jerkoch/SwipeCellKit/develop/Screenshots/Expansion-Delegate.gif" /></p>
<pre class="highlight swift"><code><span class="k">var</span> <span class="nv">options</span> <span class="o">=</span> <span class="kt">SwipeOptions</span><span class="p">()</span>
<span class="n">options</span><span class="o">.</span><span class="n">expansionDelegate</span> <span class="o">=</span> <span class="kt">ScaleAndAlphaExpansion</span><span class="o">.</span><span class="k">default</span>
</code></pre>

<p>The <code><a href="Structs/ScaleAndAlphaExpansion.html">ScaleAndAlphaExpansion</a></code> type provides a static <code>default</code> configuration, but it can also be instantiated with custom parameters to suit your needs.</p>

<p>You can also provide your own completely custom expansion behavior by adopting the <code><a href="Protocols/SwipeExpanding.html">SwipeExpanding</a></code> protocol. The protocol allows you to customize the animation timing parameters prior to initiating the (un)expansion animation, as well as customizing the action during (un)expansion.</p>
<h2 id='vertically-centered-swipe-actions-for-tall-cells' class='heading'>Vertically Centered Swipe Actions for Tall Cells</h2>

<p>If your cells are tall, then it can be useful to have the swipe actions centered relative to the visible portion of the cell.</p>

<p align="center"><img src="https://raw.githubusercontent.com/halleygen/SwipeCellKit/vertical-centring/Screenshots/Vertical-Centering.gif" /></p>

<p>This is enabled once the <code>func visibleRect(for tableView: UITableView) -&gt; CGRect?</code> or <code>func visibleRect(for collectionView: UICollectionView) -&gt; CGRect?</code> in your <code><a href="Classes/SwipeTableViewCell.html">SwipeTableViewCell</a></code>&lsquo;s or <code><a href="Classes/SwipeCollectionViewCell.html">SwipeCollectionViewCell</a></code>&rsquo;s delegate returns a non-nil <code>CGRect</code>. This function should return a rectangle of the <em>visible</em> portion of your scroll view (<code>UITableView</code> or <code>UICollectionView</code>) that is in the scroll view&rsquo;s own coordinate system. The visible portion of the scroll view refers to the part that is not obscurred by other views (e.g. a navigation bar or a toolbar).</p>

<p>If you are targeting iOS 11+ then this is simple thanks to the safe area API and your delegate function could simply be:</p>
<pre class="highlight swift"><code><span class="kd">func</span> <span class="nf">visibleRect</span><span class="p">(</span><span class="k">for</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">CGRect</span><span class="p">?</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">tableView</span><span class="o">.</span><span class="n">safeAreaLayoutGuide</span><span class="o">.</span><span class="n">layoutFrame</span>
<span class="p">}</span>
</code></pre>

<p>On earlier iOS versions you will need to calculate this rectangle yourself. In the case where a scroll view controller is embedded in a navigation controller the delegate function could be:</p>
<pre class="highlight swift"><code><span class="kd">func</span> <span class="nf">visibleRect</span><span class="p">(</span><span class="k">for</span> <span class="nv">tableView</span><span class="p">:</span> <span class="kt">UITableView</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">CGRect</span><span class="p">?</span> <span class="p">{</span>
        <span class="k">let</span> <span class="nv">topInset</span> <span class="o">=</span> <span class="n">navigationController</span><span class="p">?</span><span class="o">.</span><span class="n">navigationBar</span><span class="o">.</span><span class="n">frame</span><span class="o">.</span><span class="n">height</span> <span class="p">??</span> <span class="mi">0</span>
        <span class="k">let</span> <span class="nv">bottomInset</span> <span class="o">=</span> <span class="n">navigationController</span><span class="p">?</span><span class="o">.</span><span class="n">toolbar</span><span class="p">?</span><span class="o">.</span><span class="n">frame</span><span class="o">.</span><span class="n">height</span> <span class="p">??</span> <span class="mi">0</span>
        <span class="k">let</span> <span class="nv">bounds</span> <span class="o">=</span> <span class="n">tableView</span><span class="o">.</span><span class="n">bounds</span>

        <span class="k">return</span> <span class="kt">CGRect</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="n">bounds</span><span class="o">.</span><span class="n">origin</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="n">bounds</span><span class="o">.</span><span class="n">origin</span><span class="o">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">topInset</span><span class="p">,</span> <span class="nv">width</span><span class="p">:</span> <span class="n">bounds</span><span class="o">.</span><span class="n">width</span><span class="p">,</span> <span class="nv">height</span><span class="p">:</span> <span class="n">bounds</span><span class="o">.</span><span class="n">height</span> <span class="o">-</span> <span class="n">bottomInset</span><span class="p">)</span>
    <span class="p">}</span>
</code></pre>

<p>Refer to the included Mail app sample to see a working example.</p>

          </section>
        </section>
        <section id="footer">
          <p>&copy; 2018 <a class="link" href="https://twitter.com/mkurabi" target="_blank" rel="external">Mohammad Kurabi</a>. All rights reserved. (Last updated: 2018-05-26)</p>
          <p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v0.8.4</a>, a <a class="link" href="http://realm.io" target="_blank" rel="external">Realm</a> project.</p>
        </section>
      </article>
    </div>
  </body>
</div>
</html>
